Глава 10

Управление приложением

Приложение ColdFusion представляет собой набор Web-страниц, работающих совместно. Приложения могут быть простыми, как гостевая .книга, или сложными, как полноценная торговая система с каталогами, покупательскими корзинами и отчетами. Вы можете объединять индивидуальные приложения для разработки развитых Web-систем, создавая специальный конфигурационный файл Application.cfm, размещая его в корневом каталоге приложения. Все другие, конфигурационные файлы в приложении хранятся в каталогах ниже корневого.

Структура приложения ColdFusion основана на четырех основных компонентах:

При помощи этих компонентов можно легко объединять ваши страницы прикладных приложений ColdFusion в сложные Web-приложения.

ColdFusion предлагает свойства прикладного уровня (Application-level), которые помогут вам контролировать настройки, переменные параметры и характеристики, доступные во всем приложении. Как только вы определите приложение, можете использовать характеристики прикладного уровня наряду со всеми другими возможностями ColdFusion.

Планирование структуры приложения

Важным шагом в проектировании приложения ColdFusion является планирование структуры его каталогов. Прежде, чем начать создавать приложение, назначьте для него корневой каталог. Страницы приложения могут храниться в подкаталогах.

Загружая ту или иную страницу ColdFusion, система ищет файл Application.cfm во всех каталогах, вплоть до корневого каталога приложения, и при первой удачной попытке содержимое найденного файла помещается в начало загруженной ColdFusion-страницы.

Файл Application.cfm выполняется перед каждой прикладной страницей, которой он управляет. Вы также можете указать файл OnRequestEnd.cfm, который будет выполняться после каждой прикладной страницы в том же приложении.

ColdFusion ищет файл OnRequestEnd.cfm в том же каталоге, что и файл Application.cfm текущей страницы приложения. Файл OnRequestEnd.cfm никогда не будет выполняться, если он находится в другом каталоге, а также, если на данной странице имеется ошибка или исключение или если данная страница выполняет теги <CFABORT> или <CFEXIT>.

Так же, как файл Application.cfm нужно записывать с заглавной буквы А, так и имя файла OnRequestEnd.cfm следует писать с заглавными буквами О, R, и Е.

Определение корневого каталога для страниц приложения имеет ряд преимуществ: .

Вы можете использовать один файл Application.cfm для вашего приложения или различные файлы Application.cfm для управления отдельными секциями приложения.

для всего приложения (слева) и различные файлы Application.cfm для отдельных секций приложения (справа)

В примере слева существует проект под названием MyLineCruises, который использует один файл Application.cfm, расположенный в корневом каталоге приложения и предназначенный для обработки всех запросов на страницах приложения.

Иллюстрация справа показывает, как проект Web-Individual использует настройки в индивидуальных файлах Application.cfm, чтобы задать обработку для приложений ColdFusion на "местном" уровне. Здесь страницы каталогов Order и About Us обрабатываются с помощью настроек файла Application.cfm из корневого каталога, а каждый из каталогов Sample, Sketches, Publications и Links имеет собственный файл Application.cfm.

Пример файла Application.cfm

Прежде чем продемонстрировать пример конфигурационного файла приложения Application.cfm, детально разберем атрибуты тега <CFAPPLICATION> (табл. 10.1), частично затронутого в предыдущей главе.

Таблица 10.1. Описание атрибутов тега <CFAPPLICATION>

Атрибут

Описание

Возможные значения

APPLICATIONTIMEOUT




Позволяет определить жизненный цикл прикладных переменных. Необязательный атрибут


ICreateTimeSpan(d,h,m, s) # *




CLIENTMANAGEMENT




Дает возможность включать

или отключать управление

клиентскими переменными.

Необязательный атрибут

Yes

No (по умолчанию)



CLIENTSTORAGE




Отвечает за выбор механизма хранения клиентских переменных. Необязательный

атрибут

Registry (по умолчанию)

Cookie

Data Source Name


SESSIONMANAGEMENT




Позволяет включать или отключать управление переменными сессии. Необязательный атрибут

Yes

No (по умолчанию)



SESSIONTIMEOUT



Позволяет определить жизненный цикл переменных сессии. Необязательный атрибут

ICreateTimeSpan(d,h,m, s) 1 *



SETCLIENTCOOKIES





Если атрибут имеет значение Yes, ColdFusion автоматически посылает браузеру cookies <CFID> И <CFTOKEN>.

Необязательный атрибут

Yes (по умолчанию)

No




SETDOMAINCOOKIES







Позволяет устанавливать cookies <CFID> и <CFTOKEN>

для домена. Необязательный

атрибут. Для приложений,

работающих на уровне кластеров, необходимо использовать значение Yes

Yes

No (по умолчанию)






* d — дни, h — часы, m — минуты, s — секунды.

В листинге 10.1 приведен пример содержимого файла Application.cfm, где помимо определения основных характеристик приложения объявляются прикладные переменные для последующего их использования на страницах текущего проекта.

Листинг 10.1. Код конфигурационного файла Application.cfm

<CFAPPLICATION NAME="MyLineCruises"

APPLICATIONTIMEOUT="#CreateTimeSpan(0,1,0,0)#"

SESSIONTIMEOUT="#CreateTimeSpan(0,0,2,0)#"

SESSIONMANAGEMENT="Yes"

CLIENTMANAGEMENT="Yes"

SETCLIENTCOOKIES="Yes"

CLIENTSTORAGE="Registry">

<!---BGColor--->

<CFPARAM NAME="application.BGColorWin" DEFAULT="666699">

<CFPARAM NAME="application.BGColorPage" DEFAULT="White">

<!--- Database configuration --->

<CFPARAM NAME="application.dsn" DEFAULT="Cruise">

<!---SMTP -

<CFPARAM NAME="application.smtp" DEFAULT="127.0.0.1">

<!---POP--->

<CFPARAM NAME="application.pop" DEFAULT="127.0.0.1">

<!---Message Error--->

<CFPARAM NAME="application.msgErrorLogin"

DEFAULT="You have entered not the correct data!">

<CFPARAM NAME="application.msgErrorl"

DEFAULT="E-Mail(Login) should consist from more than 5 symbols, where there should be a symbol @">

<CFPARAM NAME="application.msgError2"

DEFAULT="Password should consist from more than 4 symbols">

<CFPARAM NAME="application.msgError3"

DEFAULT="Password should not consist only of numbers">

<CFPARAM NAME="application.msgError4"

DEFAULT="Password and Confirm, should be identical">

<CFPARAM NAME="application.msgError5"

DEFAULT="First Name, should not be empty">

<CFPARAM NAME="application.msgError6"

DEFAULT="Last Name, should not be empty">

<CFPARAM NAME="application.msgError7"

DEFAULT="Birthday, should have a format dd-mm-yyyy">

Приведенный пример нельзя воспринимать как идеальный, хотя бы по той причине, что мы еще ни слова не проронили об обработке ошибок, где одним из методов является использование конфигурационного файла приложения. Но об этом позже (см. главу 15).

Тег <CFINCLUDE>

Для каждой прикладной страницы ColdFusion всегда обрабатывается только один файл Application.cfm. Присутствие файла Application.cfm — это, по существу, наличие скрытого тега <CFINCLUDE>. Если этот файл присутствует в древе каталогов, то не включить его невозможно. Следовательно, это идеальное местоположение, чтобы установить переменные уровня приложения.

Когда требуемая прикладная страница имеет тег <CFINCLUDE>, указывающий на дополнительную прикладную страницу, ColdFusion не производит другой поиск по древу каталогов, основываясь на включенной странице приложения. Это важная для понимания особенность. После открытия требуемой прикладной страницы ColdFusion ищет файл Application.cfm только один раз.

К примеру, создадим файл-шаблон с наименованием MyHEAD.cfm для последующего включения во все необходимые нам страницы следующим образом:

<CFINCLUDE TEMPLATE = "../MyHEAD.cfm">

Здесь путь указан так, что поиск созданного нами шаблона MyHEAD.cfm будет осуществляться в каталоге на один уровень выше, куда собственно говоря мы его и поместим. Однако если на одном уровне со страницей, куда был помещен тег <CFINCLUDE>, находится файл Application.cfm, то именно этот файл и будет включен в код страницы независимо от существования такого же файла конфигурации уже на одном уровне с шаблоном MyHEAD.cfm.

Механизм хранения клиентских переменных

Как мы уже отмечали в предыдущей главе, в ColdFusion существует три возможных механизма хранения клиентских переменных.

На рис. 10.1 показана страница администратора "ColdFusion Administrator", открытая в разделе Server | Server Setting | Client Variables (Сервер | Параметры сервера | Клиентские переменные), где предоставляется возможность визуально изменять механизм хранения клиентских переменных.

Рис. 10.1. Страница "ColdFusion Administrator", раздел Client Variables

Хранение клиентских переменных в системном реестре предполагает расположение объявленных переменных в следующем разделе My Computer\ HKEY_LOCAL_MACHINE\SOFTWARE\Allaire\ColdFusion\CurrentVersion\Clients\.

Позволим себе более детально описать механизм хранения клиентских переменных с использованием базы данных, т. к. этот механизм, по мнению автора, требует особого пояснения.

Хранение клиентских переменных в базе данных

Для- использования базы данных в качестве хранилища клиентских переменных в первую очередь, следует сформировать эту базу и создать к ней источник данных (Date Source). Причем средства ColdFusion позволяют формировать необходимую структуру данных при непосредственном выборе механизма хранения переменных. Однако организовать подобную структуру данных можно и вручную. Для этого следует создать таблицы CDATA и CGLOBAL.

Описание структуры таблицы CDATA приведено в табл. 10.2.

Таблица 10.2. Структура таблицы СОЛТА

Поле

Формат

Описание

cfid

 

 

арр

 

data

Текстовое поле длиной до 20 символов

 

 

Текстовое поле длиной до 64 символов

Memo-поле

Хранит комбинацию двух встроенных переменных CFID (идентификатор клиента) и CFTOKEN (произвольно сгенерированный номер, являющийся уникальным идентификатором конкретного клиента)

Хранит имя приложения

Хранит перечень объявленных клиентских переменных, отделенных друг от друга символом #. Например, "MYFIRST cv=values#"

Описание структуры таблицы CGLOBAL приведено в табл. 10.3.

Таблица 10.3. Структура таблицы CGLOBAL

Поле

Формат

Описание

cfid

 

data

 


Ivisit

Текстовое поле до 20 символов

Memo-поле

 

 

Поле даты/времени

Хранит комбинацию двух встроенных переменных CFID И CFTOKEN

Хранит комбинацию трех встроенных переменных: HitCount (количество запросов к странице, произведенных клиентом), Lastvisit (дата и время последнего посещения страницы клиентом) и TimeCreated (дата и время, когда CFID и CFTOKEN были созданы для данного клиента)

Хранит дату и время последнего посещения страницы клиентом

После создания базы данных следует сформировать источник данных (Date Source), как это было описано в главе 1. Для нашей базы данных мы создаем источник с именем CF_CLIENT.

Следующим шагом на странице администратора "ColdFusion Administrator" в разделе Server | Server Setting | Client Variables (Сервер | Параметры сервера | Клиентские переменные) необходимо выбрать созданный источник и нажать на кнопку Add Client Variable Store (Добавить хранилище клиентских переменных). На рис. 10.2 показана страница администратора "ColdFusion Administrator" в режиме диалога для добавления нового хранилища клиентских переменных.

Рис. 10.2. Режим диалога для добавления нового хранилища клиентских переменных

В предоставленном диалоге можно установить очистку данных клиента, которые остаются неиспользуемыми в течение определенного времени, так же в этом диалоге можно включать или отключать модернизацию глобальных клиентских переменных, и как мы уже отмечали, здесь же допустимо включить или отключить автоматическое формирование таблиц с необходимыми полями в указанной базе данных.

Поскольку мы уже заранее сформировали необходимые таблицы для хранения клиентских переменных, флажок, отвечающий за создание этих таблиц (Create Client database tables (Создать таблицы базы данных для клиентских переменных)), сбрасываем. После чего нажимаем кнопку Submit Changes (Отправить изменения), тем самым подтверждаем добавление нового хранилища клиентских переменных.

На рис. 10.3 показан результат добавления нового хранилища. Здесь же в качестве текущего хранилища клиентских переменных выбрано только что добавленное хранилище.

Рис. 10.3. Результат добавления нового хранилища клиентских переменных

Надо отметить, что выбранное хранилище распространяется на приложения, не включающие атрибут CLIENTSTORAGE тега <CFAPPLICATION>, о котором уже так много было сказано.

Например, для определенного приложения можно индивидуально указать хранилище клиентских переменных, воспользовавшись тегом <СFAPPLICATION> следующим образом:

<CFAPPLICATION NAME="MyLineCruises"

APPLICATIONTIMEOUT="#CreateTimeSpan(0,1,0,0)#"

SESSIONTIMEOUT="#CreateTimeSpan(0,0,2,0)1"

SESSIONMANAGEMENT="Yes"

CLIENTMANAGEMENT="Yes"

SETCLIENTCOOKIES="Yes"

CLIENTSTORAGE="CF_CLIENT">

В этом случае для приложения "My-LineCruises" клиентские переменные будут храниться в созданной нами базе данных CF_CLIENT.

Для просмотра данных можно воспользоваться любым приложением, позволяющим строить запросы к базам данных.

Из примера видно, что клиент с идентификатором 7 последний раз посетил страницу приложения 30 мая 2001 года, а всего подобных посещений было произведено 10. При этом в базе данных хранятся две клиентские переменные: MYFIRST_CV со значением values и MYSECOND cv со значением ю.

Использование блокировок <CFLOCK>

В примерах, демонстрирующих работу с переменными сессий, прикладными переменными и серверными переменными, мы уже отмечали использование тега <CFLOCK>, предназначенного для организации блокировок в ColdFusion.

Понимая, что с одним и тем же приложением могут работать сразу несколько пользователей, существует вероятность что, к одним и тем же данным или, например, к одной и той же прикладной переменной может последовать несколько обращений в один промежуток времени, что приведет к нежелательному результату.

Отказ от использования блокировок способен привести к следующим непредсказуемым и нежелательным последствиям:

Для блокировки, гарантирующей целостность данных, необходимо использовать тег <CFLOCK>. Блокировать данные можно как для монопольного использования данных — эксклюзивно (exclusive lock), так и для многократного выполнения запросов — только для чтения (read only lock).

Вернемся к одному из наших примеров, где применяется эксклюзивная блокировка для последующего удаления прикладной переменной

textFieldSize:

<CFLOCK TIMEOUT="30" SCOPE="Application" TYPE="Exclusive">

<CFSET StructDelete(Application, "textFieldSize")> </CFLOCK>

Здесь для указания типа блокировки существует атрибут TYPE. Необязательный атрибут SCOPE позволяет определить такие области воздействия, как Session, Application или Server. Атрибут SCOPE является взаимоисключающим с атрибутом NAME, который определяет наименование блокировки. Заметим также, что в данном примере присутствует обязательный атрибут TIMEOUT, предназначенный для определения максимального периода времени (в секундах), в течение которого будет совершена попытка блокировки выполнения команд — в данном случае, команды удаления переменной.

Если попытка блокировки оказывается неудачной, дальнейшее поведение будет зависеть от значения необязательного атрибута THROWONTIMEOUT. Атрибут <THROWONTIMEOUT> определяет условие прерывания и может принимать значения Yes или NO. При значении Yes, которое является значением по умолчанию, генерируется исключительная ситуация, чтобы обеспечить уведомление о прерывании. При значении NO выполнение кода продолжается за рамками тега </CFLOCK>.

На странице "ColdFusion Administrator", показанной на рис. 10.4, в списке установок сервера Server Settings (Параметры сервера) находится пункт Locking (Блокировка), позволяющий управлять установками блокировок.

Рис. 10.4. Страница "ColdFusion Administrator", раздел Locking

Здесь вам предоставляется возможность указать тип автоматической блокировки ДЛЯ каждого типа переменных: Server, Application И Session.

Замечание

Не следует использовать включение такого типа автоматической блокировки, как Full checking (Полная проверка) в сочетании с применением в блокировке атрибута NAME.

Также на странице "ColdFusion Administrator" существует флажок Single Threading Sessions (Последовательная обработка сессий), сброшенный по умолчанию. Если установить эту опцию, тогда каждая сессия рассматривается сервером как единственная. В результате запрос от одного клиента должен закончиться прежде, чем следующий клиент сможет его осуществить. В этом случае нет необходимости блокировать переменные сессий, однако страницы, основанные на фреймах, необходимо устранить, чтобы предотвратить одновременное использование запросов из составных фреймов.

Использование <CFLOCK> по отношению к CFML-конструкциям, которые способствуют изменениям разделенных данных, гарантирует последовательную модификацию этих данных, так же, как например, использование <CFLOCK> при манипуляции с файлами обеспечивает успешную модернизацию этих файлов.